package com.niiwoo.civet.trade.service.local.refund;

import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.base.enums.RefundTypeEnum;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.*;
import com.niiwoo.civet.trade.enums.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


/**
 * Created by bincun on 2018/10/8.
 */
@Service
@Slf4j
public class RefundStatusHandlerService {
    @Autowired
    private ProjectMapperExt projectMapperExt;
    @Autowired
    private ProjectBorrowerSummaryMapperExt projectBorrowerSummaryMapperExt;
    @Autowired
    private ProjectBorrowerPlanNewMapperExt projectBorrowerPlanNewMapperExt;
    @Autowired
    private ProjectInvestOrderMapperExt projectInvestOrderMapperExt;
    @Autowired
    private InvestorCreditorMapperExt investorCreditorMapperExt;
    @Autowired
    private ProjectInvestorPlanMapperExt projectInvestorPlanMapperExt;
    @Autowired
    private ProjectGuaranteePlanMapperExt projectGuaranteePlanMapperExt;
    @Autowired
    private RefundOrderMapperExt refundOrderMapperExt;
    @Autowired
    private ProjectBorrowerPlanDetailMapperExt projectBorrowerPlanDetailMapperExt;

    //138个标的号写死
    //private final static Long[] projectIdArrary = new Long[]{478921L,781955L,1764306L,2130856L,2318229L,2518091L,2539271L,2573894L,2911437L,2964375L,2998836L,3205449L,3220778L,3499678L,3378313L,3794293L,3866701L,3912847L,3947888L,4012535L,4269344L,4296036L,4300470L,4333288L,4415602L,4393604L,4404907L,4381638L,4433771L,4447187L,4503452L,4542164L,4570710L,4599369L,4619619L,4677694L,4650392L,4777643L,4795996L,4894488L,4911274L,4877208L,4945223L,4975421L,5007198L,5031955L,5052966L,3979179L,5123107L,5233269L,5271294L,5315278L,5332521L,5333023L,5389794L,5338620L,5434593L,5404938L,5422481L,2184156L,5475403L,5427583L,5440418L,5500980L,5512700L,5616853L,5790162L,5929988L,5962007L,5971965L,5980354L,5984213L,6007798L,6009585L,6012741L,6025822L,6025872L,6026125L,6028470L,6029929L,6036567L,6051299L,6058852L,6056983L,6080264L,6083803L,6084447L,6090897L,6095972L,6096129L,6096446L,6097196L,6098377L,6100167L,6094967L,6104624L,6107679L,6119176L,6120095L,6120204L,6125347L,6126751L,6131091L,6133333L,6138079L,6143346L,6153317L,6165078L,6170776L,6177704L,6178288L,6178576L,6178817L,6196146L,6199512L,6200054L,6201578L,6202126L,6202891L,6205749L,6206355L,6208607L,6210173L,6217995L,6219546L,6222979L,6233901L,6282433L,6282661L,6315230L,6316741L,6321410L,6324179L,6327173L,6327514L,6327551L,6327725L,79401095105015808L};

    public void handle(){
        List<Long> projectIds = projectBorrowerPlanNewMapperExt.selectAllNotRefundAndAmountZeroList();
        RefundStatusHandlerService refundStatusHandlerService = (RefundStatusHandlerService)AopContext.currentProxy();
        log.info("待处理标的总数={}，project_IDs={}",projectIds.size(),JSON.toJSONString(projectIds));
        for (Long projectId : projectIds) {
            try {
                refundStatusHandlerService.doHandlerOneProject(projectId);
            }catch (Exception e){
                log.error("标的处理异常,标的号{}",projectId,e);
            }
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.READ_COMMITTED)
    public void doHandlerOneProject(Long projectId){
        Project projectUpdater = new Project();
        projectUpdater.setProjectId(projectId);

        ProjectBorrowerSummary projectBorrowerSummaryUpdater = new ProjectBorrowerSummary();
        projectBorrowerSummaryUpdater.setProjectId(projectId);

        Project project = projectMapperExt.selectByPrimaryKeyForUpdate(projectId);
        log.info("日志记录one，锁定待处理标的对象，project={}", JSON.toJSONString(project));

        //待还总金额（不区分费用）
        BigDecimal refundingMoneyTotal = projectBorrowerPlanDetailMapperExt.selectTotalAmountByProjectId(projectId);

        //查询待还为0，状态未收款的还款计划
        List<Long> planIdList =  projectBorrowerPlanNewMapperExt.selectNotRefundAndAmountZeroList(projectId);


        log.info("日志记录two，projectId={},refundingMoneyTotal={},planNewList={}",projectId,refundingMoneyTotal, JSON.toJSONString(planIdList));
        for (Long planId : planIdList) {
            ProjectBorrowerPlanNew planNew = projectBorrowerPlanNewMapperExt.selectByPrimaryKey(planId);
            ProjectBorrowerPlanNew planNewUpdater = new ProjectBorrowerPlanNew();
            planNewUpdater.setId(planNew.getId());
            //最后还款日订单 (1还款 2垫付 3代还 )
            RefundOrder refundOrderLastRefund = refundOrderMapperExt.selectByProjectIdAndTradeType(projectId,Arrays.asList(new Byte[]{1,3}),planNew.getPeriod());

            //最后回款订单
            RefundOrder refundOrderLastRefundAndGuarantee = refundOrderMapperExt.selectByProjectIdAndTradeType(projectId,Arrays.asList(new Byte[]{1,2,3}),planNew.getPeriod());

            log.info("日志记录three，refundOrderLastRefund={},refundOrderLastRefundAndGuarantee={},planNew={}",refundOrderLastRefund,refundOrderLastRefundAndGuarantee, JSON.toJSONString(planNew));

            //标的已还清
            if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0) {
                projectUpdater.setStatus(ProjectStatusEnum.FINISH.getStatus());
                projectBorrowerSummaryUpdater.setRepayStatus(RepayStatusEnum.SETTLEMENT.getCode());
            }
            if (refundOrderLastRefund != null){
                if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0) {
                    projectBorrowerSummaryUpdater.setOverTime(refundOrderLastRefund.getOverTime());
                }
                planNewUpdater.setOverCurrentDate(refundOrderLastRefund.getCurrentDate());
                planNewUpdater.setOverDate(refundOrderLastRefund.getOverTime());

                if (refundOrderLastRefund.getRefundType().equals(RefundTypeEnum.OVERDEPT.getRefundType())){
                    if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0) {
                        projectUpdater.setSubStatus(ProjectSubStatusEnum.FINISH_ADVANCE.getSubStatus());
                    }
                    planNewUpdater.setStatus(BorrowerPlanRefundStatusEnum.OVER_DEBT_REPAYMENT.getCode());
                }else if (refundOrderLastRefund.getRepayStatus().equals(RepayStatusEnum.NORMAL.getCode())){
                    if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0) {
                        projectUpdater.setSubStatus(ProjectSubStatusEnum.FINISH_NORMAL.getSubStatus());
                    }
                    planNewUpdater.setStatus(BorrowerPlanRefundStatusEnum.NORMAL_REPAYMENT.getCode());
                }else if (refundOrderLastRefund.getRepayStatus().equals(RepayStatusEnum.OVERDUE.getCode())){
                    if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0) {
                        projectUpdater.setSubStatus(ProjectSubStatusEnum.FINISH_OVERDUE.getSubStatus());
                    }
                    planNewUpdater.setStatus(BorrowerPlanRefundStatusEnum.OVERDUE_REPAYMENT.getCode());
                }else if (refundOrderLastRefund.getRepayStatus().equals(RepayStatusEnum.BADLOANS.getCode())){
                    if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0) {
                        projectUpdater.setSubStatus(ProjectSubStatusEnum.FINISH_BAD.getSubStatus());
                    }
                    planNewUpdater.setStatus(BorrowerPlanRefundStatusEnum.OVERDUE_REPAYMENT.getCode());
                }else {
                    log.info("未知状态数据,refundOrderLastRefund={}",JSON.toJSONString(refundOrderLastRefund));
                }
                log.info("还款计划状态变更 planNewUpdater = {},planNewOri={}",JSON.toJSONString(planNewUpdater),JSON.toJSONString(planNew));
                planNewUpdater.setUpdateTime(new Date());
                projectBorrowerPlanNewMapperExt.updateByPrimaryKeySelective(planNewUpdater);

                //担保公司回款计划
                List<ProjectGuaranteePlan> projectGuaranteePlans = projectGuaranteePlanMapperExt.listProjectPeriodGuaranteePlan(projectId,planNew.getPeriod());
                for (ProjectGuaranteePlan guaranteePlan : projectGuaranteePlans) {
                    if (guaranteePlan.getTotalPenaltyFee().compareTo(guaranteePlan.getReceivedPenaltyFee()) == 0
                            && guaranteePlan.getInterest().compareTo(guaranteePlan.getReceivedInterest()) == 0
                            && guaranteePlan.getCapital().compareTo(guaranteePlan.getReceivedCapital()) == 0 ){
                        Date currentDate = refundOrderLastRefundAndGuarantee.getCurrentDate();
                        ProjectGuaranteePlan projectGuaranteePlanUpdater = new ProjectGuaranteePlan();
                        projectGuaranteePlanUpdater.setId(guaranteePlan.getId());
                        projectGuaranteePlanUpdater.setOverTime(refundOrderLastRefundAndGuarantee.getOverTime());
                        projectGuaranteePlanUpdater.setOverCurrentDate(currentDate);
                        projectGuaranteePlanUpdater.setReceivedStatus(Byte.valueOf("2"));//已收款
                        log.info("投资人回款计划状态变更 projectInvestorPlanUpdater = {},guaranteePlan={}",JSON.toJSONString(projectGuaranteePlanUpdater),JSON.toJSONString(guaranteePlan));
                        projectGuaranteePlanUpdater.setUpdateTime(new Date());
                        projectGuaranteePlanMapperExt.updateByPrimaryKeySelective(projectGuaranteePlanUpdater);
                    }
                }
            }else {
                //记录数据。
                log.info("没有查询到还款订单,projectId={},current_period={}",projectId,planNew.getPeriod());
                throw new RuntimeException("更新失败,标的号"+projectId);
            }
            if (refundOrderLastRefundAndGuarantee != null){
                //投资人回款计划
                List<ProjectInvestorPlan> projectInvestorPlanList = projectInvestorPlanMapperExt.listProjectPeriodInvestorPlan(projectId,planNew.getPeriod());
                for (ProjectInvestorPlan investorPlan : projectInvestorPlanList) {
                    if (investorPlan.getTotalPenaltyFee().compareTo(investorPlan.getReceivedPenaltyFee()) == 0
                            && investorPlan.getInterest().compareTo(investorPlan.getReceivedInterest()) == 0
                            && investorPlan.getCapital().compareTo(investorPlan.getReceivedCapital()) == 0 ){
                        Date currentDate = refundOrderLastRefundAndGuarantee.getCurrentDate();
                        ProjectInvestorPlan projectInvestorPlanUpdater = new ProjectInvestorPlan();
                        projectInvestorPlanUpdater.setId(investorPlan.getId());
                        projectInvestorPlanUpdater.setOverTime(refundOrderLastRefundAndGuarantee.getOverTime());
                        projectInvestorPlanUpdater.setOverCurrentDate(currentDate);
                        if (PeriodUnitEnum.MONTH.getValue().equals(project.getDeadlineUnit())
                                && investorPlan.getCurrentPeriod() != 1
                                && (investorPlan.getReceivedDate().after(new DateTime(currentDate).plusMonths(1).minusDays(1).toDate()))){
                            projectInvestorPlanUpdater.setReceivedStatus(Byte.valueOf("4"));//提前结清
                        }else if (currentDate.before(investorPlan.getReceivedDate()) || DateUtils.isSameDay(currentDate, investorPlan.getReceivedDate())){
                            projectInvestorPlanUpdater.setReceivedStatus(Byte.valueOf("2"));//正常收款
                        }else {
                            projectInvestorPlanUpdater.setReceivedStatus(Byte.valueOf("3"));//逾期收款
                        }
                        log.info("投资人回款计划状态变更 projectInvestorPlanUpdater = {},investorPlan={}",JSON.toJSONString(projectInvestorPlanUpdater),JSON.toJSONString(investorPlan));
                        projectInvestorPlanUpdater.setUpdateTime(new Date());
                        projectInvestorPlanMapperExt.updateByPrimaryKeySelective(projectInvestorPlanUpdater);
                    }
                }
            }else {
                log.info("没有查询到回款订单,projectId={},current_period={}",projectId,planNew.getPeriod());
                throw new RuntimeException("更新失败,标的号"+projectId);
            }
            //待还为0 才执行更新
            if (BigDecimal.ZERO.compareTo(refundingMoneyTotal) == 0 ) {
                //原来标的状态是还款中 --> 结清
                if (project.getStatus().equals(ProjectStatusEnum.REPAYING.getStatus())) {
                    log.info("更新标的状态为结清,projectUpdater={},projectBorrowerSummaryUpdater={}",JSON.toJSONString(projectUpdater),JSON.toJSONString(projectBorrowerSummaryUpdater));
                    projectUpdater.setUpdateTime(new Date());
                    projectMapperExt.updateByPrimaryKeySelective(projectUpdater);
                    projectBorrowerSummaryUpdater.setUpdateTime(new Date());
                    projectBorrowerSummaryMapperExt.updateByPrimaryKeySelective(projectBorrowerSummaryUpdater);

                    List<ProjectInvestOrder> projectInvestOrderList = projectInvestOrderMapperExt.selectInvestedList(projectId);
                    for (ProjectInvestOrder investOrder : projectInvestOrderList) {
                        if (investOrder.getEvolutionStatus().equals(ProjectInvestOrderEvolutionStatusEnum.BACKING.getValue())
                                || investOrder.getEvolutionStatus().equals(ProjectInvestOrderEvolutionStatusEnum.BACKING_OVERDUE.getValue())){
                            ProjectInvestOrder investOrderUpdater = new ProjectInvestOrder();
                            investOrderUpdater.setId(investOrder.getId());
                            investOrderUpdater.setEvolutionStatus(ProjectInvestOrderEvolutionStatusEnum.ALL_BACKED.getValue());
                            log.info("投资订单更新为结清,标的号{},investOrderId={}",investOrder.getProjectId(),investOrder.getId());
                            investOrderUpdater.setUpdateTime(new Date());
                            projectInvestOrderMapperExt.updateByPrimaryKeySelective(investOrderUpdater);
                        }
                    }

                    List<InvestorCreditor> investorCreditors = investorCreditorMapperExt.selectByInvestOrderIdsByProjectId(projectId);
                    for (InvestorCreditor investorCreditor : investorCreditors) {
                        if (InvestorCreditorStatusEnum.NORMAL_RECEIVING.getStatus().equals(investorCreditor.getStatus())
                                || InvestorCreditorStatusEnum.RECEIVE_OVERDUE.getStatus().equals(investorCreditor.getStatus())){
                            InvestorCreditor projectInvestorCreditorUpdater = new InvestorCreditor();
                            projectInvestorCreditorUpdater.setId(investorCreditor.getId());
                            projectInvestorCreditorUpdater.setStatus(InvestorCreditorStatusEnum.FINISH.getStatus());
                            log.info("债权数据更新为结清,标的号{},investorCreditorId={}",investorCreditor.getProjectId(),investorCreditor.getId());
                            projectInvestorCreditorUpdater.setUpdateTime(new Date());
                            investorCreditorMapperExt.updateByPrimaryKeySelective(projectInvestorCreditorUpdater);
                        }
                    }
                }else {
                    log.info("标的号已结清,projectSubStatus={}，还款计划状态未结清,projectId={},原planNew={}",project.getSubStatus(),projectId,JSON.toJSON(planNew));
                }
            }else {
                //没有结清的情况下，需要维护摘要表 当前期
                ProjectBorrowerPlanNew projectBorrowerPlanNew = projectBorrowerPlanNewMapperExt.selectNextNotRefunPeriod(projectId);
                ProjectBorrowerSummary summaryOri = projectBorrowerSummaryMapperExt.selectByPrimaryKey(projectId);

                if (projectBorrowerPlanNew != null && projectBorrowerPlanNew.getRefundDate().after(summaryOri.getRefundDate())) {
                    ProjectBorrowerSummary projectBorrowerSummaryUpdater2 = new ProjectBorrowerSummary();
                    projectBorrowerSummaryUpdater2.setProjectId(projectId);
                    projectBorrowerSummaryUpdater2.setRefundDate(projectBorrowerPlanNew.getRefundDate());
                    projectBorrowerSummaryUpdater2.setAutoRefundDate(projectBorrowerPlanNew.getRefundDate());
                    projectBorrowerSummaryUpdater2.setCurrentPeriod(projectBorrowerPlanNew.getPeriod());
                    if (summaryOri.getRefundDate().before(projectBorrowerSummaryUpdater2.getRefundDate())) {
                        projectBorrowerSummaryUpdater2.setPreviousRefundDate(summaryOri.getRefundDate());
                    }
                    log.info("更新标的摘要信息当前期数,projectBorrowerSummaryUpdater2={},summaryOri={}", JSON.toJSONString(projectBorrowerSummaryUpdater2), JSON.toJSONString(summaryOri));
                    projectBorrowerSummaryUpdater2.setUpdateTime(new Date());
                    projectBorrowerSummaryMapperExt.updateByPrimaryKeySelective(projectBorrowerSummaryUpdater2);
                }
            }

        }
    }
}
